package com.bookrecomm.controller;

import com.bookrecomm.entity.Book;
import com.bookrecomm.service.BookService;
import com.bookrecomm.vo.BookVO;
import com.bookrecomm.vo.PageVO;
import com.bookrecomm.vo.ResultVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

/**
 * 图书控制器
 * 处理图书相关的请求
 */
@RestController
@RequestMapping("/books")
public class BookController {

    @Autowired
    private BookService bookService;

    /**
     * 根据ID查询图书
     * @param id 图书ID
     * @return 图书信息
     */
    @GetMapping("/{id}")
    public ResultVO<BookVO> getBookById(@PathVariable Long id) {
        BookVO bookVO = bookService.findById(id);
        return ResultVO.success("获取成功", bookVO);
    }

    /**
     * 分页查询图书列表
     * @param page 页码（从1开始）
     * @param size 每页大小
     * @param sort 排序字段，可以是图书实体类的属性名称，特殊值"default"会映射到createdAt
     * @param order 排序方向（asc/desc）
     * @return 分页图书列表
     */
    @GetMapping
    public ResultVO<PageVO<BookVO>> getBooks(
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(defaultValue = "createdAt") String sort,
            @RequestParam(defaultValue = "desc") String order) {
        
        // 处理特殊的排序字段值
        if ("default".equalsIgnoreCase(sort)) {
            sort = "createdAt"; // 将"default"映射到创建时间字段
        }
        
        // 创建分页参数（注意：Spring Data的页码从0开始）
        Sort.Direction direction = "asc".equalsIgnoreCase(order) ? Sort.Direction.ASC : Sort.Direction.DESC;
        Pageable pageable = PageRequest.of(page - 1, size, Sort.by(direction, sort));
        
        try {
            // 查询图书列表
            PageVO<BookVO> pageVO = bookService.findAll(pageable);
            return ResultVO.success("获取成功", pageVO);
        } catch (Exception e) {
            // 如果排序字段无效，使用默认排序
            if (e instanceof org.springframework.data.mapping.PropertyReferenceException) {
                pageable = PageRequest.of(page - 1, size, Sort.by(direction, "createdAt"));
                PageVO<BookVO> pageVO = bookService.findAll(pageable);
                return ResultVO.success("获取成功（使用默认排序）", pageVO);
            }
            return ResultVO.clientError("获取图书列表失败: " + e.getMessage());
        }
    }

    /**
     * 根据分类ID查询图书列表
     * @param categoryId 分类ID
     * @param page 页码（从1开始）
     * @param size 每页大小
     * @return 分页图书列表
     */
    @GetMapping("/category/{categoryId}")
    public ResultVO<PageVO<BookVO>> getBooksByCategory(
            @PathVariable Long categoryId,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size) {
        
        // 创建分页参数
        Pageable pageable = PageRequest.of(page - 1, size);
        
        // 查询图书列表
        PageVO<BookVO> pageVO = bookService.findByCategoryId(categoryId, pageable);
        return ResultVO.success("获取成功", pageVO);
    }

    /**
     * 根据标签ID查询图书列表
     * @param tagId 标签ID
     * @param page 页码（从1开始）
     * @param size 每页大小
     * @return 分页图书列表
     */
    @GetMapping("/tag/{tagId}")
    public ResultVO<PageVO<BookVO>> getBooksByTag(
            @PathVariable Long tagId,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size) {
        
        // 创建分页参数
        Pageable pageable = PageRequest.of(page - 1, size);
        
        // 查询图书列表
        PageVO<BookVO> pageVO = bookService.findByTagId(tagId, pageable);
        return ResultVO.success("获取成功", pageVO);
    }

    /**
     * 搜索图书
     * @param keyword 关键词
     * @param page 页码（从1开始）
     * @param size 每页大小
     * @return 分页图书列表
     */
    @GetMapping("/search")
    public ResultVO<PageVO<BookVO>> searchBooks(
            @RequestParam String keyword,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size) {
        
        // 创建分页参数
        Pageable pageable = PageRequest.of(page - 1, size);
        
        // 搜索图书
        PageVO<BookVO> pageVO = bookService.search(keyword, pageable);
        return ResultVO.success("搜索成功", pageVO);
    }

    /**
     * 获取推荐图书列表
     * @param userId 用户ID，可为null表示未登录用户
     * @param limit 限制数量
     * @return 推荐图书列表
     */
    @GetMapping("/recommendations")
    public ResultVO<List<BookVO>> getRecommendations(
            @RequestParam(required = false) Long userId,
            @RequestParam(defaultValue = "10") int limit) {
        
        List<BookVO> books = bookService.getRecommendations(userId, limit);
        return ResultVO.success("获取成功", books);
    }

    /**
     * 获取热门图书列表
     * @param limit 限制数量
     * @return 热门图书列表
     */
    @GetMapping("/hot")
    public ResultVO<List<BookVO>> getHotBooks(
            @RequestParam(defaultValue = "10") int limit) {
        
        List<BookVO> books = bookService.getHotBooks(limit);
        return ResultVO.success("获取成功", books);
    }

    /**
     * 获取新书列表
     * @param limit 限制数量
     * @return 新书列表
     */
    @GetMapping("/new")
    public ResultVO<List<BookVO>> getNewBooks(
            @RequestParam(defaultValue = "10") int limit) {
        
        List<BookVO> books = bookService.getNewBooks(limit);
        return ResultVO.success("获取成功", books);
    }

    /**
     * 添加图书（仅管理员可操作）
     * @param book 图书信息
     * @return 添加后的图书信息
     */
    @PostMapping
    @PreAuthorize("hasRole('ADMIN')")
    public ResultVO<BookVO> addBook(@Valid @RequestBody Book book) {
        BookVO bookVO = bookService.addBook(book);
        return ResultVO.success("添加成功", bookVO);
    }

    /**
     * 更新图书信息（仅管理员可操作）
     * @param id 图书ID
     * @param book 图书信息
     * @return 更新后的图书信息
     */
    @PutMapping("/{id}")
    @PreAuthorize("hasRole('ADMIN')")
    public ResultVO<BookVO> updateBook(
            @PathVariable Long id,
            @Valid @RequestBody Book book) {
        
        BookVO bookVO = bookService.updateBook(id, book);
        return ResultVO.success("更新成功", bookVO);
    }

    /**
     * 删除图书（仅管理员可操作）
     * @param id 图书ID
     * @return 删除结果
     */
    @DeleteMapping("/{id}")
    @PreAuthorize("hasRole('ADMIN')")
    public ResultVO<Boolean> deleteBook(@PathVariable Long id) {
        boolean success = bookService.deleteBook(id);
        return ResultVO.success("删除成功", success);
    }

    /**
     * 更新图书状态（仅管理员可操作）
     * @param id 图书ID
     * @param status 状态：0-下架，1-上架
     * @return 更新结果
     */
    @PutMapping("/{id}/status")
    @PreAuthorize("hasRole('ADMIN')")
    public ResultVO<Boolean> updateStatus(
            @PathVariable Long id,
            @RequestParam Integer status) {
        
        boolean success = bookService.updateStatus(id, status);
        return ResultVO.success("更新成功", success);
    }
}
